local tokens_key = KEYS[1] -- 限流的key
local timestamp_key = KEYS[2] -- 限流的key

local rate = tonumber(ARGV[1]) --每秒生产令牌数量
local capacity = tonumber(ARGV[2]) -- 桶容量（并发数量）
local now = tonumber(ARGV[3]) -- 时间戳
local requested = tonumber(ARGV[4]) -- 每次请求消耗令牌数量

local fill_time = capacity/rate -- 存满桶耗时
local ttl = math.floor(fill_time*2) -- 返回小于fill_time*2的整数值作为过期时间

-- 获取已使用的令牌数量
local last_tokens = tonumber(redis.call("get", tokens_key))
if last_tokens == nil then
  last_tokens = capacity
end

-- 获取当前时间时间是否已经存在
local last_refreshed = tonumber(redis.call("get", timestamp_key))
if last_refreshed == nil then
  last_refreshed = 0
end

local delta = math.max(0, now-last_refreshed)
local batch_tokens = 1
-- 每秒产生的令牌数量小于1， 则token等于桶容量（并发数量）
if rate < 1 then
  batch_tokens = capacity
end
-- 剩余令牌数
local filled_tokens = math.min(capacity, last_tokens+(math.floor(delta*rate) * batch_tokens))
-- 剩余令牌数是否大于等于每次请求消耗令牌数量
local allowed = filled_tokens >= requested
-- 新的令牌数量等于剩余令牌数量
local new_tokens = filled_tokens
-- 剩余数量等于0
local allowed_num = 0
local timestamp = now
-- 剩余令牌数小于每次请求消耗令牌数量且当前时间时间已经存在则参数不变，否则timestamp等于当前时间【标识当前秒还没有请求】
if not(allowed) and last_refreshed > 0 then
  timestamp = last_refreshed
end
-- 剩余令牌数大于等于每次请求消耗令牌数量 ，那么新的令牌数量等于剩余令牌数减去每次请求消耗令牌数量，
if allowed then
  new_tokens = filled_tokens - requested
  allowed_num = 1
end

redis.call("setex", tokens_key, ttl, new_tokens)
redis.call("setex", timestamp_key, ttl, timestamp)

return { allowed_num, new_tokens }
